package com.ciaojian.core.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ciaojian.core.enums.business.CouponCodeOriginEnum;
import com.ciaojian.core.model.CouponCode;
import com.ciaojian.core.model.vo.CouponExpiredTimeVo;
import com.ciaojian.core.model.vo.CouponVo;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;

import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 券码 mapper
 *
 * @author Atlakyn
 */
@Mapper
public interface CouponCodeMapper extends BaseMapper<CouponCode> {

    /**
     * 获取购买权益订单发放的外部券码
     *
     * @param orderId 订单ID
     * @return 外部券码
     */
    String getOutsideCodeByOrderId(Integer orderId);

    /**
     * 获取购买权益订单包含的优惠券
     *
     * @param orderId 订单ID
     * @return 订单包含的优惠券
     */
    List<Map<String, Object>> getCouponCodeBelongOrder(Integer orderId);

    /**
     * 获取用户特定的优惠券
     *
     * @param userId 用户ID
     * @return /
     */
    List<Map<String, Object>> getSpecialUserCouponCode(@Param("userId") Integer userId);

    /**
     * 查询用户优惠券历史信息
     *
     * @param page   分页插件
     * @param userId 用户 id
     * @return 分页列表
     */
    Page<Map<String, Object>> pageCouponHistory(Page<Map<String, Object>> page, @Param("userId") Integer userId);

    /**
     * 给用户券
     *
     * @param userId   用户 id
     * @param couponId 券 id
     * @return 修改结果
     */
    @Update("UPDATE d_coupon_code SET status = 1,origin = 2 " +
            "WHERE coupon_id = #{couponId} " +
            "AND user_id = #{userId} " +
            "AND status = 0 " +
            "LIMIT 1")
    Boolean updateByUserIdAndCouponId(@Param("userId") Integer userId, @Param("couponId") Integer couponId);

    /**
     * 给用户券
     *
     * @param userId    用户 id
     * @param couponIds 券id数组
     * @return 修改结果
     */
    Boolean updateByUserIdAndCouponIds(@Param("userId") Integer userId,@Param("orderId") Integer orderId, @Param("couponIds") String[] couponIds);

    /**
     * 给用户添加一张券
     *
     * @param userId      用户
     * @param couponId    券码
     * @param origin      来源
     * @param expiredTime 过期时间
     * @return 修改结果
     */
    @Update("UPDATE d_coupon_code SET status = 1, " +
            "origin = #{origin}, " +
            "user_id = #{userId}, " +
            "expired_time = #{expiredTime} " +
            "WHERE coupon_id  = #{couponId} " +
            "AND status = 0 " +
            "LIMIT 1")
    Boolean updateByCouponId(@Param("userId") Integer userId,
                             @Param("couponId") Integer couponId,
                             @Param("origin") CouponCodeOriginEnum origin,
                             @Param("expiredTime") Date expiredTime);

    /**
     * 取一张未被领取的券
     *
     * @param couponId 券类型
     * @param userId   用户
     * @param endDate  结束时间
     * @return 未被领取的券
     */
    CouponCode giveStock(@Param("userId") Integer userId,
                         @Param("couponId") Integer couponId,
                         @Param("endDate") Date endDate);


    /**
     * 根据券码类型统计剩余券码的数量
     *
     * @param couponId 券码类型
     * @return 数量
     */
    Integer countRemainByCouponId(@Param("couponId") String couponId);


    List<CouponVo> getCouponCodeByUserId(@Param("userId") Integer userId,
                                         @Param("total") String total,
                                         @Param("state") Boolean state,
                                         @Param("storeId") Integer storeId,
                                         @Param("serviceId") Integer serviceId,
                                         @Param("dayOfWeek") Integer dayOfWeek
    );

    /**
     * 根据兑换码获取券码
     *
     * @param code 券码
     */
    CouponCode getByExchange(String code);

    /**
     * 从库存中给用户发放一张券
     *
     * @param userId      用户ID
     * @param origin      券码来源
     * @param expiredTime 过期时间
     * @param couponId    券码ID
     * @return TRUE 成功
     */
    Boolean giveSingleCouponCode(@Param("userId") Integer userId,
                                 @Param("origin") CouponCodeOriginEnum origin,
                                 @Param("expiredTime") Date expiredTime,
                                 @Param("couponId") Integer couponId);

    @Select("select\n" +
            "        cc.coupon_id as couponeId,cc.user_id as userId,cc.expired_time as expiredTime,u.openid as openid,c.title,c.reduction \n" +
            "        from d_coupon_code cc\n" +
            "        LEFT JOIN d_user u on cc.user_id = u.id\n" +
            "        LEFT JOIN d_coupon c on cc.coupon_id = c.id " +
            "        where\n" +
            "       \t  cc.status =1  and UNIX_TIMESTAMP(cc.expired_time)-UNIX_TIMESTAMP(NOW()) BETWEEN 412000 and 518400 order by cc.user_id limit #{current},#{page}") //412000 and 518400
    List<CouponExpiredTimeVo> couponExpiredTime(int current,int page);

    @Select("select\n" +
            "        count(cc.coupon_id) \n" +
            "        from d_coupon_code cc\n" +
            "        LEFT JOIN d_user u on cc.user_id = u.id\n" +
            "        where\n" +
            "       \t  cc.status =1  and UNIX_TIMESTAMP(cc.expired_time)-UNIX_TIMESTAMP(NOW()) BETWEEN 412000 and 518400  ") //412000 and 518400

    int couponExpiredNum();


    /**
     * 删除用户券
     */
    @Update("update d_coupon_code set status = 0,user_id=null,origin=null,order_id=null where code = #{code} limit 1;")
    void removeUserCoupon(@Param("code") String code);

    Integer selectMemberCount(@Param("userId") Integer userId);
}
